package GUI;

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Iterator;
import java.util.TreeMap;
import java.util.Map.Entry;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.JToolBar;
import javax.swing.ScrollPaneConstants;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;

import Client.DBTransaction;
import DBTools.DBProcess;
import Structure.MeaningWordPair;
import Structure.Word;

/**
 * allows to open a connection to a mongodb, search for words/translations, show these in the gui. Allow 
 * to clear the database.
 * @author Tony
 *
 */
public class GodGUI {

	private JFrame frame;
	private final DBTransaction dbTransaction;
	private final DBProcess dbProcess;
	private JTextField txtQuery;
	private JTextPane answerPane;
	private JButton btnTranslate;
	private StyledDocument document;
	// for filling the comboboxes
	private final TreeMap<String, String> langCodes;
	private JComboBox<String> sourceLangComboBox, destLangComboBox;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {

		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					GodGUI window = new GodGUI();
					window.frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public GodGUI() {
		this.langCodes = new TreeMap<String, String>();

		// read langCodes from File and write them into the Map
		try {
			BufferedReader bf = new BufferedReader(new FileReader(
					"properties/deLangCodes.txt"));
			String tmp;
			while ((tmp = bf.readLine()) != null) {
				String[] splits = tmp.split(";");
				langCodes.put(splits[0], splits[1]);
			}

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();

		}
		initialize();
		dbProcess = new DBProcess();
		dbTransaction = new DBTransaction();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frame = new JFrame();
		frame.setBounds(100, 100, 450, 300);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.getContentPane().setLayout(new BorderLayout(0, 0));

		JPanel panel = new JPanel();
		frame.getContentPane().add(panel, BorderLayout.NORTH);
		panel.setLayout(new GridLayout(0, 1, 0, 0));

		JToolBar dbToolbar = new JToolBar();
		panel.add(dbToolbar);
		dbToolbar.setFloatable(false);

		final JButton btnStartStopDB = new JButton("Start Database");
		btnStartStopDB.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (btnStartStopDB.getText().equals("Start Database")) {
					dbProcess.start();
					btnStartStopDB.setText("Stop Database");
				} else {
					dbProcess.stop();
					btnStartStopDB.setText("Start Database");
				}
			}
		});
		dbToolbar.add(btnStartStopDB);

		final JButton btnConnect = new JButton("Connect");
		btnConnect.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				dbTransaction.connect();
				SimpleAttributeSet attributes = new SimpleAttributeSet();
				attributes.addAttribute(StyleConstants.CharacterConstants.Bold,
						Boolean.TRUE);
				try {
					document.insertString(document.getLength(), "connected",
							attributes);
				} catch (BadLocationException badLocationException) {
					System.err.println("Bad insert");
				}
				answerPane.setDocument(document);
				btnTranslate.setEnabled(true);

			}
		});
		dbToolbar.add(btnConnect);

		JButton btnCleanDB = new JButton("Clean Database");
		btnCleanDB.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				dbTransaction.deleteDBContent();
			}
		});
		dbToolbar.add(btnCleanDB);

		JToolBar queryToolbar = new JToolBar();
		queryToolbar.setFloatable(false);
		panel.add(queryToolbar);

		txtQuery = new JTextField();
		txtQuery.setText("Stuhl");
		queryToolbar.add(txtQuery);
		txtQuery.setColumns(10);
		txtQuery.addKeyListener(new KeyListener() {
			@Override
			public void keyTyped(KeyEvent e) {
				// not needed
			}

			@Override
			public void keyReleased(KeyEvent e) {
				if (e.getKeyCode() == KeyEvent.VK_ENTER) {
					btnTranslate.doClick();
				}
			}

			@Override
			public void keyPressed(KeyEvent e) {
				// not needed
			}
		});

		btnTranslate = new JButton("translate");
		queryToolbar.add(btnTranslate);
		btnTranslate.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				query();
			}
		});
		btnTranslate.setEnabled(false);

		JToolBar langToolbar = new JToolBar();
		langToolbar.setFloatable(false);
		frame.getContentPane().add(langToolbar, BorderLayout.SOUTH);

		sourceLangComboBox = new JComboBox<String>();
		sourceLangComboBox.setMaximumRowCount(5);
		Iterator<String> it = this.langCodes.keySet().iterator();
		sourceLangComboBox.addItem("- alle -");
		while (it.hasNext()) {
			sourceLangComboBox.addItem(it.next());
		}
		sourceLangComboBox.setSelectedItem("Deutsch");
		langToolbar.add(sourceLangComboBox);

		destLangComboBox = new JComboBox<String>();
		destLangComboBox.setMaximumRowCount(5);
		it = this.langCodes.keySet().iterator();
		destLangComboBox.addItem("- alle -");
		while (it.hasNext()) {
			destLangComboBox.addItem(it.next());
		}
		
		destLangComboBox.setSelectedItem("Englisch");

		langToolbar.add(destLangComboBox);

		this.document = new DefaultStyledDocument();

		this.answerPane = new JTextPane();
		answerPane.setEditable(false);

		JScrollPane scrollPane = new JScrollPane(answerPane);
		scrollPane
				.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
	}

	private void query() {
		String word = txtQuery.getText().trim();
		Word[] answers = dbTransaction.findTranslations(word,
				this.langCodes.get(this.sourceLangComboBox.getSelectedItem()),
				this.langCodes.get(this.destLangComboBox.getSelectedItem()),
				null);
		SimpleAttributeSet attributesBold = new SimpleAttributeSet();
		SimpleAttributeSet attributesNonBold = new SimpleAttributeSet();
		attributesNonBold.addAttribute(StyleConstants.CharacterConstants.Bold,
				Boolean.FALSE);
		attributesBold.addAttribute(StyleConstants.CharacterConstants.Bold,
				Boolean.TRUE);
		
		try {
			this.document.remove(0, this.document.getLength());
			// iterate over all answers (mostly only one)
			for (int i = 0; i < answers.length; i++) {
				this.document.insertString(this.document.getLength(), "word: "
						+ answers[i].word + "\tlanguage: ", attributesNonBold);
				// language of word is bold
				this.document.insertString(this.document.getLength(),
						answers[i].language, attributesBold);
				
				//explanation
				this.document.insertString(this.document.getLength(), "\n\texplenation", attributesBold);
				for(Entry<String,String> meaningToExplanation: answers[i].mapMeaningToExplanation.entrySet()){
					this.document.insertString(this.document.getLength(),
							"\n\t"+meaningToExplanation.getKey()+"\t"+meaningToExplanation.getValue(), attributesNonBold);
				}
				
				
				// iterate over Translations of the word
				for (int j = 0; j < answers[i].translations.length; j++) {
					this.document.insertString(this.document.getLength(),
							"\n\n\t" + answers[i].translations[j].language,
							attributesBold);

					// iterate over Meanings of translation
					for (int k = 0; k < answers[i].translations[j].meaningWordMap.size(); k++) {
						MeaningWordPair meaningWordMap=answers[i].translations[j].meaningWordMap.get(k);
						this.document.insertString(
								this.document.getLength(),
								"\n\t"
										+ meaningWordMap.meaning
										+ "\t"
										+ meaningWordMap.word
										, attributesNonBold);
					}
				}
				this.document.insertString(this.document.getLength(), "\n",
						attributesNonBold);
			}
		} catch (BadLocationException e) {
			e.printStackTrace();
		}

		this.answerPane.setDocument(this.document);
	}
}
